package player

import (
	"context"
	"github.com/tianjigames/fairy/constants"
	"github.com/tianjigames/fairy/manager"
	protos2 "github.com/tianjigames/fairy/protos"
	"github.com/topfreegames/pitaya"
	"github.com/topfreegames/pitaya/component"
	"github.com/topfreegames/pitaya/logger"
)

type PlayerHandler struct {
	component.Base
}

func NewPlayerHandler() *PlayerHandler {
	return &PlayerHandler{}
}

/**
获取一个全局唯一的sessionId
*/
func (p *PlayerHandler) OnSessionCreated(ctx context.Context,req *protos2.GatePOnSessionCreated) (*protos2.GatePOnSessionCreatedRet,error) {
	return &protos2.GatePOnSessionCreatedRet{
		SessionId: manager.OnlinePlayerManager.GenerateSessionId(),
	},nil
}

/**
处理客户端连接关闭
*/
func (p *PlayerHandler) OnSessionClosed(ctx context.Context,req *protos2.GatePOnSessionClosed) (*protos2.GatePOnSessionClosedRet,error) {
	//查找等待登录游戏服务器所在的登录服务器 给登录服务器发送玩家连接消息 登录服务器做相应处理
	if req.SessionIds != nil && len(req.SessionIds) > 0 {
		svId := ""
		for _,sessionId := range req.SessionIds {
			if len(svId) == 0 {
				svId = manager.OnlinePlayerManager.GetPlayerOnLoginServerId(sessionId)
			}

			manager.OnlinePlayerManager.RemovePlayerOnLoginServer(sessionId)
			//如果玩家已经登录 删除绑定
			manager.OnlinePlayerManager.RemoveAccountBindSessionIdBySessionId(sessionId)
		}

		if len(svId) > 0 {
			//玩家在登录服务器上 给玩家推送消息
			reply := &protos2.GatePOnSessionClosedRet{}
			err := pitaya.RPCTo(ctx,svId, constants.PHOnSessionClosedRoute,reply,req)
			if err != nil {
				logger.Log.Errorf("[GateDealer] onSessionClosed failed,error=%s",err.Error())
			}
		}

		//todo:玩家在游戏服上的处理逻辑
	}



	return &protos2.GatePOnSessionClosedRet{},nil
}

/**
玩家关联了loginServer
 */
func (p *PlayerHandler) PlayerOnLoginServer(ctx context.Context,req *protos2.LPSessionOnLoginServer) (*protos2.PLSessionOnLoginServerRet,error) {
	manager.OnlinePlayerManager.SetPlayerOnLoginServerId(req.SessionId,req.ServerId)
	return &protos2.PLSessionOnLoginServerRet{},nil
}

/**
账户绑定session处理
 */
func (p *PlayerHandler) AccountBindSession(ctx context.Context,req *protos2.LPAccountBindSession) (*protos2.PLAccountBindSessionRet,error) {

	oldSessionId := manager.OnlinePlayerManager.GetAccountBindSessionId(req.AccountId)
	if len(oldSessionId) > 0 {//玩家已经登录过 可能在某个登录服上 也可能在某个游戏服上
		svId := manager.OnlinePlayerManager.GetPlayerOnLoginServerId(oldSessionId)
		if len(svId) > 0 {//给服务器推送消息 踢出这个session下线
			err := pitaya.RPC(ctx, constants.PHOnSessionClosedRoute,&protos2.GatePOnSessionClosedRet{},&protos2.GatePOnSessionClosed{
				SessionIds: []string{oldSessionId},
			})

			if err != nil {
				logger.Log.Errorf("[Player] AccountBindSession failed,error:%s",err.Error())
				return nil,err
			}
		}
		manager.OnlinePlayerManager.RemovePlayerOnLoginServer(oldSessionId)
		_,err := pitaya.SendKickToUsers([]string{oldSessionId}, constants.SvTypeConnector)
		if err != nil {
			logger.Log.Errorf("[Player] AccountBindSession failed,error:%s",err.Error())
			return nil,err
		}

		//todo:玩家在游戏服务上 给游戏服务器推送消息 踢出玩家下线
	}
	//账户绑定新的session
	manager.OnlinePlayerManager.BindAccountSessionId(req.AccountId,req.SessionId)
	return &protos2.PLAccountBindSessionRet{},nil
}

/**
获取所有游侠服务器上的人数
 */
func (p *PlayerHandler) GetOnGameServerPlayerNum(ctx context.Context,req *protos2.WPOnGameServerPlayerNum) (*protos2.PWOnGameServerPlayerNumRet,error) {
	return &protos2.PWOnGameServerPlayerNumRet{
		Num: int32(manager.OnlinePlayerManager.GetOnGameServerPlayerNum()),
	},nil
}
